package mgo

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
	"github.com/docker/go-connections/nat"
	"testing"
)

/**
 *  author : Tuo
 *  e-mail : tuojie@ijovo.com
 *  time   : 2021/10/7 4:50 下午
 *  desc   : TODO
 *  version: 1.0
 */

const image = "mongo"

const containerPort = "27017/tcp"

func RunWithMongoInDocker(m *testing.M, mongoURI *string) int {
	c, err := client.NewClientWithOpts()

	if err != nil {
		panic(err)
	}

	ctx := context.Background()

	resp, err := c.ContainerCreate(
		ctx,
		&container.Config{
			Image:        image,
			ExposedPorts: nat.PortSet{containerPort: {}},
		},
		&container.HostConfig{
			PortBindings: nat.PortMap{
				containerPort: []nat.PortBinding{
					{
						HostIP:   "127.0.0.1",
						HostPort: "0",
					},
				},
			},
		}, nil, nil, "",
	)

	if err != nil {
		panic(err)
	}

	containerID := resp.ID

	defer func() {
		err = c.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{
			Force: true,
		})
		if err != nil {
			panic(err)
		}
	}()

	err = c.ContainerStart(ctx, containerID, types.ContainerStartOptions{})
	if err != nil {
		panic(err)
	}

	inspect, err := c.ContainerInspect(ctx, containerID)
	if err != nil {
		panic(err)
	}

	host := inspect.NetworkSettings.Ports[containerPort][0]
	*mongoURI = fmt.Sprintf("mongodb://%s:%s/", host.HostIP, host.HostPort)

	return m.Run()
}
